/**
 * @file kilb.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-10-20
 *
 * @copyright Copyright (c) 2022
 *
 */



#include "comm/types.h"
#include "tools/kilb.h"
#include "tools/log.h"
#include "comm/cpu_instr.h"

void pannic(const char *file, int line, const char *func, const char *cond)
{
    log_printf("assert failed! %s ", cond);
    log_printf("file: %s\nline: %d\nfunc:%s", file, line, func);
    for(;;){
        hlt();
    }
}

/**
 * @brief copy string
 *
 * @param dest Destination String(address/pointe)
 * @param src Source String(address/pointe)
 */
void kernel_strcpy(char *dest, const char *src)
{
    if (!dest || !src)
    {
        return;
    }
    char *d = dest;
    const char *s = src;
    while (*d && *s)
    {
        *d++ = *s++;
    }
    *d = '\0';
}
/**
 * @brief copy string limit size
 *
 * @param dest Destination String(address/pointe)
 * @param src Source String(address/pointe)
 * @param size limit copy size in source string
 */
void kernel_strncpy(char *dest, const char *src, int size)
{
    if (!dest || !src || !size)
    {
        return;
    }
    char *d = dest;
    const char *s = src;
    while ((size-- > 0) && *s)
    {
        *d++ = *s++;
    }
    // size=0, add a end symbol in destination string
    if (size == 0)
    {
        *(d - 1) = '\0';
    }
    // size!=0, source string's length  shorter than size, so add a '\0'
    else
    {
        *d = '\0';
    }
}
/**
 * @brief compare the sting is same? true return zero
 *
 * @param s1 string one
 * @param s2 string two
 * @param size size of compare
 * @return int  return zero symbol string is same: but define same of string is different of c standard
 */
int kernel_strncmp(const char *s1, const char *s2, int size)
{
    if (!s1 || !s2 || !size)
    {
        return -1;
    }
    while (*s1 && *s2 && (*s1 == *s2) && size)
    {
        s1++;
        s2++;
    }
    return !((*s1 == '\0') || (*s2 == '\0') || (*s1 == *s2));
}
/**
 * @brief return the length of string
 *
 * @param str  input String
 * @return int value is length of string (not include '\0')
 */
int kernel_strlen(const char *str)
{
    if (!str)
    {
        return -1;
    }

    uint32_t len = 0;
    const char *s = str;
    while (*s)
    {
        len++;
        s++;
    }
    return len;
}

/**
 * @brief copy memory limit size
 *
 * @param dest Destination pointe/address
 * @param src Source pointe/address
 * @param size size limit copy size in source address
 * @return int return 1 is ok!
 */
int kernel_memcpy(void *dest, void *src, int size)
{
    if (!dest || !src || !size)
    {
        return -1;
    }
    uint8_t *p_d = (uint8_t *)dest;
    uint8_t *p_s = (uint8_t *)src;
    while (size--)
    {
        *p_d++ = *p_s++;
    }
}
/**
 * @brief let specified memory address begin set value v, length is size.
 *
 * @param dest Destination pointe/address
 * @param v value
 * @param size  limit set size in source address
 * @return int  return 1
 */
int kernel_memset(void *dest, uint8_t v, int size)
{
    if (!dest || !size)
    {
        return -1;
    }
    uint8_t *p_d = (uint8_t *)dest;
    while (size--)
    {
        *p_d++ = v;
    }
    return 1;
}
/**
 * @brief compare the specified memory address begin value is smae
 *
 * @param d1 memory address
 * @param d2 memory address
 * @param size limit size
 * @return int return 0
 */
int kernel_memcmp(void *d1, void *d2, int size)
{
    if (!d1 || !d2 || !size)
    {
        return -1;
    }
    uint8_t *p_d = (uint8_t *)d1;
    uint8_t *p_s = (uint8_t *)d2;
    while (size--)
    {
        if (*p_d++ != *p_s++)
        {
            return -1;
        }
    }
    return 0;
}
/**
 * @brief 计算字符串的数量
 */
int strings_count(char **start)
{
    int count = 0;
    // 注意是2维指针
    if (start)
    {
        while (*start++)
        {
            count++;
        }
    }
    return count;
}
/**
 * @brief 从路径中解释文件名
 */
char *get_file_name(const char *name){
    char *s = (char* )name;
    while (*s != '\0')
    {
        s++;
    }
    while ((*s != '/') && (*s != '\\') && (s >= name))
    {
        s--;
    }

    return ++s;
}
